<template>
  <div class="app-container">
    <div class="filter-container">
      <span v-for="(c,i) in showConditions" :key="i" style="margin-left: 5px;">
        <el-input
          v-if="c.type=='input'"
          v-model="listQuery[c.property]"
          size="small"
          :placeholder="c.label"
          style="width: 200px; "
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
        <el-date-picker
          v-else-if="c.type=='date-range'"
          v-model="listQuery[c.property]"
          type="daterange"
          value-format="yyyy-MM-dd"
          align="left"
          unlink-panels
          range-separator="至"
          :start-placeholder="c.label+':  开始'"
          end-placeholder="结束"
          :picker-options="pickerOptions"
          size="small"
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
        <el-date-picker
          v-else-if="c.type=='date'"
          v-model="listQuery[c.property]"
          type="date"
          value-format="yyyy-MM-dd"
          align="left"
          unlink-panels
          :placeholder="c.label"
          :picker-options="pickerOptions"
          size="small"
          class="filter-item"
          @keyup.enter.native="handleFilter"
        />
      </span>
      <el-button v-waves class="filter-item" size="small" type="primary" icon="el-icon-search" @click="handleFilter">
        查询
      </el-button>
      <el-button class="filter-item" style="margin-left: 10px;" size="small" type="primary" icon="el-icon-edit" @click="handleCreate">
        添加
      </el-button>
      <el-button class="filter-item" style="margin-left: 0px;" size="small" icon="el-icon-setting" @click="pageSettingVisible=true">
        页面设置
      </el-button>
    </div>

    <el-table
      :key="tableKey"
      v-loading="listLoading"
      :data="list"
      border
      fit
      highlight-current-row
      style="width: 100%;"
      @sort-change="sortChange"
      @header-dragend="headerDragend"
    >

      <!-- 行展开，显示的详细信息 -->
      <el-table-column v-if="isExpandedRow" type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="demo-table-expand">
            <el-form-item
                    v-for="(col, index) in showTheads4Details"
                    :label="col.label" >
              <span>{{ props.row[col.property] }}</span>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>


      <el-table-column
        v-for="(col, index) in showTheads"
        :key="index"
        :prop="col.property"
        :sortable="col.sort"
        :sort-orders="['ascending', 'descending']"
        :label="col.label"
        :width="col.width"
      >
        <template slot-scope="{row}">
          <span v-if="col.edit">
            <el-input v-if="row.edit" v-model="row[col.property]" class="edit-input" size="mini" />
            <span v-else>{{ row[col.property] }}</span>
          </span>
          <span v-else>{{ row[col.property] }}</span>
        </template>
      </el-table-column>

      <!--操作Button-->
      <el-table-column v-if="!isDropMenu" fixed="right" label="操作" align="center" min-width="230">
        <template slot="header">
          <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
            平铺 > 下拉
          </el-checkbox>
        </template>
        <template slot-scope="{row}">
          <el-button v-show="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="cancelEdit(row)">取消</el-button>
          <el-button v-if="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="confirmEdit(row)">保存</el-button>
          <el-button v-else type="primary" size="mini" style="margin-left: 0px;" @click="row.edit=!row.edit">编辑</el-button>
          <el-button slot="reference" size="mini" type="danger" @click="handleDelete(row, $index)">删除</el-button>
        </template>
      </el-table-column>

      <el-table-column v-else fixed="right" label="操作" align="center" min-width="140">
        <template slot="header">
          <el-checkbox v-model="isDropMenu" class="filter-item" style="margin-left:15px;" @change="tableKey=tableKey+1">
            下拉 > 平铺
          </el-checkbox>
        </template>
        <template slot-scope="{row, $index}">
          <el-button v-show="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="cancelEdit(row)">取消</el-button>
          <el-button v-if="row.edit" type="success" size="mini" style="margin-left: 0px;" @click="confirmEdit(row)">保存</el-button>
          <el-dropdown v-else @command="handleCommand">
            <el-button type="primary" size="mini">
              菜单<i class="el-icon-arrow-down el-icon--right" />
            </el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item :command="beforeHandleCommand(row, 'update', $index)">编辑</el-dropdown-item>
              <el-dropdown-item :command="beforeHandleCommand(row, 'delete', $index)">删除</el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </template>
      </el-table-column>

    </el-table>

    <!-- 分页 -->
    <pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />

    <!-- 添加弹出框 -->
    <el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
      <form-details ref="formDetails" :row="row" :isFromFather="true" @createResult="createResult"/>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          保存
        </el-button>
      </div>
    </el-dialog>

    <!-- 页面设置 -->
    <el-drawer
      title="页面布局参数设置"
      :visible.sync="pageSettingVisible"
      custom-class="demo-drawer"
      ref="drawer"
      direction="rtl"
      :before-close="handleDrawerClose"
    >
      <el-scrollbar height="100%">
        <div class="demo-drawer__content" style="padding-left: 20px;">
          <el-form>
            <el-form-item>
              <label>查询条件：</label>
              <el-checkbox-group v-model="conditionCheckboxVal" style="margin-left: 20px;">
                <el-checkbox v-for="(c,i) in conditionOptions" :key="i" :label="c.property" style="width: 120px;">{{ c.label }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item>
              <label>是否展开行：</label>
              <el-checkbox v-model="isExpandedRow" style="width: 150px;">展开行显示详情</el-checkbox>
            </el-form-item>
            <el-form-item>
              <label>列表显示列：</label>
              <el-checkbox-group v-model="checkboxVal" style="margin-left: 20px;">
                <el-checkbox v-for="(thead,index) in theadOptions" :key="index" :label="thead.property" style="width: 120px;">{{ thead.label }}</el-checkbox>
              </el-checkbox-group>
            </el-form-item>
            <el-form-item>
              <label>表列宽度调整：</label>
              <span>鼠标放置在列与列中间，出现左右调整符，可左右拖动调整。</span>
            </el-form-item>
          </el-form>
        </div>
      </el-scrollbar>
      <div class="demo-drawer__footer">
        <el-button style="width: 80%;" @click="savePageSetting">关    闭</el-button>
      </div>
    </el-drawer>

  </div>
</template>

<script>
import { fetchList, updateApi, deleteApi } from './api'
import waves from '@/directive/waves' // waves directive
import { parseTime, reorgQueryParams } from '@/utils'
import storageUtil from '@/utils/StorageUtil'
import Pagination from '@/components/Pagination' // secondary package based on el-pagination
import FormDetails from './form-details.vue' // add form form dialog
// 从当前View的私有数据对象中取数据
import { ConditionShowListCkedKey, ColumnShowListCkedKey, isDropMenuKey, ColumnShowListWidthKey, IsExpandedRowCkedKey, conditionOptions, theadOptions, pickerOptions, pickerOptionsSingleDate } from './data'

export default {
    name: 'A3UserSettingComplexListLineEdit',
    components: { Pagination, FormDetails },
    directives: { waves },

    props: {
        // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
        paramDateArr: Array,
        paramTreeNode: Object
    },

    filters: {
        statusFilter(status) {
            const statusMap = {
                published: 'success',
                draft: 'info',
                deleted: 'danger'
            }
            return statusMap[status]
        }
    },

    data() {
        return {
            loading: false,
            tableKey: 0,
            // 控制行尾菜单显示模式（下拉->平铺）
            isDropMenu: storageUtil.readBool(isDropMenuKey),
            // 默认表头控制
            theadOptions: theadOptions,
            checkboxVal: [], // checkboxVal
            showTheads: [], // 默认表头 Default header
            showTheads4Details: [], // 详细信息
            // 查询条件
            conditionOptions: conditionOptions,
            conditionCheckboxVal: [], // 当前checkbox选中的值
            showConditions: [], // 当前显示的condition
            // 列表
            list: null,
            total: 0,
            listLoading: true,
            listQuery: {
                page: 1,
                limit: 20,
                createdate: [] // 不加此项，watch里监控侧边日历父组件，传的日期参数，有问题； 子页面时间查询框清不掉查询参数。
            },
            importanceOptions: [1, 2, 3],
            sortOptions: [{ label: 'ID Ascending', key: '+id' }, { label: 'ID Descending', key: '-id' }],
            statusOptions: ['published', 'draft', 'deleted'],
            dialogFormVisible: false,
            dialogStatus: '',
            textMap: {
                update: 'Edit',
                create: 'Create'
            },
            downloadLoading: false,
            pickerOptions: pickerOptions,
            pickerOptionsSingleDate: pickerOptionsSingleDate,
            row: {},
            pageSettingVisible: false, // 页面布局设置
            isExpandedRow: storageUtil.readBool(IsExpandedRowCkedKey) // 是否展开行
        }
    },

    watch: {
        conditionCheckboxVal(valArr) {
            this.showConditions = this.conditionOptions.filter(i => valArr.indexOf(i.property) >= 0)
        },
        checkboxVal(valArr) {
            this.showTheads = this.theadOptions.filter(i => valArr.indexOf(i.property) >= 0)
            this.tableKey = this.tableKey + 1// 为了保证table 每次都会重渲 In order to ensure the table will be re-rendered each time
        },
        isDropMenu(val) {
            storageUtil.saveBool(isDropMenuKey, val, true)
        },
        // 当作为侧边日历查询的子组件时，接收父组件的传值，watch中查询
        paramDateArr(val) {
            this.listQuery.createdate = val // 默认用createdate作查询参数
            this.handleFilter()
        }
    },

    created() {
        this.initLayout()
        this.getList()
    },

    methods: {
        initLayout() {
          // 显示列处理
          const defaultCheckedThead = []
          theadOptions.forEach(col => {
              if (col.show) {
                  defaultCheckedThead.push(col.property)
                  this.showTheads4Details.push(col)
              }
          })
          // read localstorage first
          const columnShowListCked = storageUtil.readArr(ColumnShowListCkedKey)
          if (columnShowListCked.length === 0) {
              this.checkboxVal = defaultCheckedThead
          } else {
              this.checkboxVal = columnShowListCked
          }
          // 查询条件处理
          const defaultCheckedCondition = []
          conditionOptions.forEach(col => {
              if (col.show) {
                  defaultCheckedCondition.push(col.property)
              }
          })
          // read localstorage first
          const showConditionsCked = storageUtil.readArr(ConditionShowListCkedKey)
          if (showConditionsCked.length === 0) {
              this.conditionCheckboxVal = defaultCheckedCondition
          } else {
              this.conditionCheckboxVal = showConditionsCked
          }
        },

        getList() {
            this.listLoading = true
            // 重组查询条件
            const params = Object.assign({}, this.listQuery)
            reorgQueryParams(params)
            // 查询
            fetchList(params).then(result => {
                const items = result.map.rows
                this.total = result.map.total

                // 备份数据，编辑还原用
                this.list = items.map(v => {
                    this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html
                    v.original = Object.assign({}, v)
                    return v
                })

                // Just to simulate the time of the request
                setTimeout(() => {
                    this.listLoading = false
                }, 0.1 * 1000)
            })
        },
        handleFilter() {
            this.listQuery.page = 1
            this.getList()
        },
        sortChange(data) {
            const { prop, order } = data
            if (prop === 'id') {
                this.sortByID(order)
            }
        },
        sortByID(order) {
            if (order === 'ascending') {
                this.listQuery.sort = '+id'
            } else {
                this.listQuery.sort = '-id'
            }
            this.handleFilter()
        },
        handleCreate() {
            this.dialogStatus = 'create'
            this.dialogFormVisible = true
            // 消除上次出现的验证信息
            this.$nextTick(() => {
                this.$refs['formDetails'].clearValidate()
                this.$refs['formDetails'].resetTemp()
            })
        },
        // 调用子组件操作数据
        createData() {
            this.$refs['formDetails'].createData()
        },
        // 子组件操作成功，回调此方法，关闭弹框、刷新
        createResult() {
            this.dialogFormVisible = false
            this.handleFilter()
        },

        cancelEdit(row) {
            // 还原原始值
            Object.keys(row).forEach(key => {
                if (key !== 'original' && key !== 'edit') {
                    row[key] = row.original[key]
                }
            })
            row.edit = false
            // row.original.edit = false
            this.$message({
                message: '数据恢复到原始值',
                type: 'warning'
            })
        },
        confirmEdit(row) {
            const param = Object.assign({}, row)
            param.original = {}
            updateApi(param).then((result) => {
                if (result.success) {
                    row.edit = false
                    // 原始值：更新成最新输入仠
                    Object.keys(row).forEach(key => {
                        if (key !== 'original' && key !== 'edit') {
                            row.original[key] = row[key]
                        }
                    })
                    this.$notify({
                        title: '成功',
                        message: '数据更新成功',
                        type: 'success',
                        duration: 2000
                    })
                }
            })
        },

        // 下拉操作菜单
        beforeHandleCommand(row, command, index) {
          return {
            'index': index,
            'row': row,
            'command': command
          }
        },
        handleCommand(command) {
          const row = command.row
          switch (command.command) {
            case 'update': {
              row.edit = !row.edit
              break
            }
            case 'delete': {
              this.handleDelete(row)
              break
            }
          }
        },
        // End

        handleDelete(row) {
          this.$confirm('确认删除吗？')
            .then(_ => {
              // delete api
              deleteApi({ id: '' + row.id }).then((result) => {
                if (result.success) {
                  this.getList()
                  this.$notify({
                    title: '成功',
                    message: '删除成功',
                    type: 'success',
                    duration: 2000
                  })
                }
              })
              // end
            })
            .catch(_ => {})
        },

        // 列宽监听，本地存储
        // 存储格式: {name: 93, url: 115, deleteflag: 140, id: 121}
        headerDragend(newWidth, oldWidth, column, event) {
            const columnWidthJson = storageUtil.readObj(ColumnShowListWidthKey)
            columnWidthJson[column.property] = newWidth
            storageUtil.saveObj(ColumnShowListWidthKey, columnWidthJson, true)
            // 实时修改全局theadOptions中的width, 不然要刷新页面才从localstorage中读取width
            theadOptions.filter(c => c.property === column.property)[0].width = newWidth
        },
        // 关闭Drawer, 自动上传数据保存
        handleDrawerClose() {
            this.savePageSetting()
        },
        // 保存页面设置参数
        savePageSetting() {
            // 查询条件
            storageUtil.saveArr(ConditionShowListCkedKey, this.conditionCheckboxVal, true)
            // 列
            storageUtil.saveArr(ColumnShowListCkedKey, this.checkboxVal, true)
            // 是否展开行
            storageUtil.saveBool(IsExpandedRowCkedKey, this.isExpandedRow, true)
            // close dialog
            this.pageSettingVisible = false
        }
    }
}
</script>
<style>
  .demo-table-expand {
    font-size: 0;
  }
  .demo-table-expand label {
    width: 100px;
    color: #99a9bf;
  }
  .demo-table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 40%;
  }
  .el-table__body tr.current-row > td {
    background-color: #F0F7FF !important;
  }
  /*表格 element-ui的table改变偶数行背景色*/
  .el-table--striped .el-table__body tr.el-table__row--striped td{
    background: #F5F7FA;
  }
  /*表格 解决element-ui的table表格控件表头与内容列不对齐问题*/
  .el-table th.gutter {
    display: table-cell!important;
  }
  /*抽屉 element-ui的drawer固定底部按钮*/
  .el-drawer__body{
    overflow-y: scroll;
    margin-bottom: 50px;
  }
  .demo-drawer__footer{
    width:100%;
    position:absolute;
    bottom:10px;
    left:10px;
    border-top: 1px solid #eee;
    padding-top: 5px;
    text-align:center;
    background-color:white;
  }
  /*抽屉 去掉element-ui的drawer标题选中状态*/
  :focus{
    outline:0;
  }

  .el-scrollbar__wrap {
    overflow-x: hidden;
  }
</style>
